package com.etl.task.handler;

import com.eksframework.commons.core.base.EksCopier;
import com.eksframework.commons.core.base.EksNumber;
import com.eksframework.commons.core.constant.ConstString;
import com.etl.enums.GoodsTypeEnum;
import com.etl.es.document.GoodsDocument;
import com.etl.es.document.OrderDocument;
import com.etl.es.repository.GoodsRepository;
import com.etl.extract.DatabaseBuilder;
import com.etl.extract.ScheduleTask;
import com.etl.extract.SqlQuery;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 商品处理类
 *
 * @author: chenfenghai
 * @version: 1.0
 * @date: 2020-10-30 9:55
 */
@Slf4j
@Component
public class GoodsHandler {

    @Autowired
    GoodsRepository goodsRepository;

    @Autowired
    DatabaseBuilder databaseBuilder;

    /**
     * 查询销售商品列表
     *
     * @param scheduleTask 调度任务信息
     * @param parameterMap SQL参数MAP
     * @return List
     */
    public List<Map<String, String>> findSaleGoodsList(
            ScheduleTask scheduleTask, Map<String, Object> parameterMap) {
        SqlQuery extractQuery = SqlQuery.builder()
                .id("com.etl.task.mapper.SaleOrderMapper.findSaleGoodsList")
                .parameterObject(parameterMap)
                .build();
        return databaseBuilder.queryData(scheduleTask, extractQuery);
    }

    /**
     * 查询退货商品列表
     *
     * @param scheduleTask 调度任务信息
     * @param parameterMap SQL参数MAP
     * @return List
     */
    public List<Map<String, String>> findRejectGoodsList(
            ScheduleTask scheduleTask, Map<String, Object> parameterMap) {
        SqlQuery extractQuery = SqlQuery.builder()
                .id("com.etl.task.mapper.RejectOrderMapper.findRejectGoodsList")
                .parameterObject(parameterMap)
                .build();
        return databaseBuilder.queryData(scheduleTask, extractQuery);
    }

    /**
     * 保存ES商品文档列表
     *
     * @param documentList ES商品文档列表
     */
    public void saveGoodsDocumentList(List<GoodsDocument> documentList) {
        if (CollectionUtils.isEmpty(documentList)) {
            return;
        }
        goodsRepository.saveAll(documentList);
    }

    /**
     * 建造ES商品文档列表
     *
     * @param orderDocument 订单文档
     * @param goodsMap      查询商品结果MAP
     * @return List-GoodsDocument
     */
    public List<GoodsDocument> buildGoodsDocumentList(
            OrderDocument orderDocument, Map<String, String> goodsMap) {
        if (Objects.isNull(goodsMap)) {
            return Lists.newArrayList();
        }
        return Stream.of(GoodsTypeEnum.values())
                .map(goodsTypeEnum -> buildGoodsDocument(orderDocument, goodsMap, goodsTypeEnum))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 建造ES商品文档
     *
     * @param orderDocument 订单文档
     * @param goodsMap      查询商品结果MAP
     * @param goodsTypeEnum 商品类型枚举
     * @return GoodsDocument
     */
    public GoodsDocument buildGoodsDocument(OrderDocument orderDocument,
                                            Map<String, String> goodsMap,
                                            GoodsTypeEnum goodsTypeEnum) {
        BigDecimal goodsPrice = EksNumber.of(goodsMap.get(goodsTypeEnum.getPriceField()))
                .toEksConverter().toBigDecimal();
        int goodsCount = EksNumber.of(goodsMap.get(goodsTypeEnum.getCountField()))
                .toEksConverter().intValue();
        if (BigDecimal.ZERO.compareTo(goodsPrice) == 0 && goodsCount == 0) {
            return null;
        }
        GoodsDocument goodsDocument = EksCopier.copy(orderDocument, GoodsDocument.class);
        goodsDocument.setOrderId(StringUtils.joinWith(
                ConstString.UNDERLINE, goodsDocument.getOrderId(), goodsTypeEnum.getCode()));
        goodsDocument.setGoodsType(goodsTypeEnum.getCode());
        goodsDocument.setGoodsTypeName(goodsTypeEnum.getText());
        goodsDocument.setGoodsPrice(goodsPrice.doubleValue());
        goodsDocument.setGoodsCount(goodsCount);
        return goodsDocument;
    }
}
